﻿using System;
using System.Data.SqlClient;
using System.Linq;
using System.Transactions;
using AB.ServiceDirectory.Commons.DataFilters;
using AB.ServiceDirectory.Entities;

namespace AB.ServiceDirectory.Dao
{
    [Serializable]
    public class TrustRegionsDao
    {
        [NonSerialized] private readonly ServicesDirectoryDataContext _context = DB.Context;

        /// <summary>
        /// Gets the list.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <param name="sortType">Type of the sort.</param>
        /// <param name="startRowIndex">Start index of the row.</param>
        /// <param name="max">The max.</param>
        /// <returns></returns>
        public IQueryable<TrustRegion> GetList(TrustRegionsFilter filter, string sortType, int startRowIndex, int max)
        {
            IQueryable<TrustRegion> data = from d in _context.TrustRegions
                                           select d;

            // 1. Filter by condition
            if (filter != null)
            {
                data = GetListQuery(data, filter);
            }

            // 2. Sorting
            data = GetListSort(data, sortType);

            // 3. Limit the rows
            data = data.Skip(startRowIndex).Take(max);
            return data;
        }

        /// <summary>
        /// Gets the list query.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="filter">The filter.</param>
        /// <returns></returns>
        private static IQueryable<TrustRegion> GetListQuery(IQueryable<TrustRegion> data, TrustRegionsFilter filter)
        {
            //  data = data.Where(d => d.CountryId == filter.CountryId);
            if (filter.BeginningLetters != null)
            {
                data = data.Where(g => filter.BeginningLetters.Contains(g.TrustRegionName[0].ToString()));
            }
            if (!filter.IncludeInactive)
            {
                //  data = data.Where(g => g.IsActive);
                data = data.Where(g => g.IsActive);
            }
            return data;
        }

        /// <summary>
        /// Gets the list sort.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="sortType">Type of the sort.</param>
        /// <returns></returns>
        private static IQueryable<TrustRegion> GetListSort(IQueryable<TrustRegion> data, string sortType)
        {
            bool sortDescending = false;
            if (!string.IsNullOrEmpty(sortType))
            {
                string[] values = sortType.Split(' ');
                sortType = values[0];
                if (values.Length > 1)
                {
                    sortDescending = (values[1] == "DESC");
                }
                switch (sortType)
                {
                    case "TrustRegionName":
                        data = sortDescending
                                   ? data.OrderByDescending(g => g.TrustRegionName)
                                   : data.OrderBy(g => g.TrustRegionName);
                        break;

                    case "Description":
                        data = sortDescending
                                   ? data.OrderByDescending(g => g.Description)
                                   : data.OrderBy(g => g.Description);
                        break;

                    case "NationCountry":
                        data = sortDescending
                                   ? data.OrderByDescending(g => g.Country.CountryName)
                                   : data.OrderBy(g => g.Country.CountryName);
                        break;

                    case "IsActive":
                        data = sortDescending
                                   ? data.OrderByDescending(g => g.IsActive)
                                   : data.OrderBy(g => g.IsActive);
                        break;
                    default:
                        data = sortDescending
                                   ? data.OrderByDescending(g => g.TrustRegionId)
                                   : data.OrderBy(g => g.TrustRegionId);
                        break;
                }
            }
            return data;
        }

        /// <summary>
        /// Gets the list count.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <returns></returns>
        public int GetListCount(TrustRegionsFilter filter)
        {
            IQueryable<TrustRegion> data = from gor in _context.TrustRegions
                                           select gor;
            if (filter != null)
            {
                data = GetListQuery(data, filter);
            }
            return data.Count();
        }

        /// <summary>
        /// Gets the trust regions id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public TrustRegion GetTrustRegionsId(int id)
        {
            TrustRegion trustRegions = _context.TrustRegions.FirstOrDefault(g => g.TrustRegionId == id);
            return trustRegions;
        }

        /// <summary>
        /// Adds the trust region.
        /// </summary>
        /// <param name="newTrustRegion">The new trust region.</param>
        /// <returns></returns>
        public bool AddTrustRegion(TrustRegion newTrustRegion)
        {
            try
            {
                using (var transaction = new TransactionScope())
                {
                    _context.TrustRegions.InsertOnSubmit(newTrustRegion);
                    _context.SubmitChanges();
                    transaction.Complete();
                    return true;
                }
            }
            catch (SqlException exception)
            {
                Log.GetLog(this).Error(exception);
                return false;
            }
        }

        /// <summary>
        /// Edits the trust regions.
        /// </summary>
        /// <param name="newTrustRegion">The new trust region.</param>
        /// <returns></returns>
        public bool EditTrustRegions(TrustRegion newTrustRegion)
        {
            TrustRegion oldTrustRegion =
                _context.TrustRegions.FirstOrDefault(d => d.TrustRegionId == newTrustRegion.TrustRegionId);
            if (oldTrustRegion != null)
            {
                Country newCountry = _context.Countries.FirstOrDefault(c => c.CountryId == newTrustRegion.CountryId);
                oldTrustRegion.TrustRegionName = newTrustRegion.TrustRegionName;
                oldTrustRegion.Country = newCountry;
                oldTrustRegion.Description = newTrustRegion.Description;

                _context.SubmitChanges();
                return true;
            }
            return false;
        }

        /// <summary>
        /// Checks the name of the trust region.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        public bool CheckTrustRegionName(string name)
        {
            TrustRegion trustRegionName = _context.TrustRegions.FirstOrDefault(d => d.TrustRegionName.Equals(name));
            return trustRegionName != null;
        }

        /// <summary>
        /// Sets the trust region status.
        /// </summary>
        /// <param name="trustRegionId">The trust region ID.</param>
        /// <param name="status">if set to <c>true</c> [status].</param>
        /// <returns></returns>
        public bool SetTrustRegionStatus(int trustRegionId, bool status)
        {
            TrustRegion trustRegion = _context.TrustRegions.FirstOrDefault(o => o.TrustRegionId == trustRegionId);
            if (trustRegion != null)
            {
                trustRegion.IsActive = status;
                _context.SubmitChanges();
                return true;
            }

            return false;
        }
    }
}